package com.ruoyi.advertisement.service.impl;

import java.util.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ruoyi.advertisement.mapper.AdvertisementStatisticsMapper;
import com.ruoyi.advertisement.service.IAdvertisementStatisticsService;

/**
 * 广告统计服务实现
 * 
 * @author ruoyi
 */
@Service
public class AdvertisementStatisticsServiceImpl implements IAdvertisementStatisticsService {
    
    @Autowired
    private AdvertisementStatisticsMapper statisticsMapper;

    @Override
    public Map<String, Object> getAdvertisementOverview(String startDate, String endDate) {
        Map<String, Object> params = buildParams(startDate, endDate);
        Map<String, Object> data = statisticsMapper.getAdvertisementOverview(params);
        
        Map<String, Object> result = new HashMap<>();
        result.put("totalPlays", getLongValue(data, "totalPlays"));
        result.put("totalViews", getLongValue(data, "totalViews"));
        result.put("totalClicks", getLongValue(data, "totalClicks"));
        result.put("avgDuration", getDoubleValue(data, "avgDuration"));
        result.put("completionRate", getDoubleValue(data, "completionRate"));
        result.put("clickRate", getDoubleValue(data, "clickRate"));
        
        return result;
    }

    @Override
    public Map<String, Object> getPlayTrendData(String startDate, String endDate, Long materialId) {
        Map<String, Object> params = buildParams(startDate, endDate);
        if (materialId != null) {
            params.put("materialId", materialId);
        }
        
        List<Map<String, Object>> data = statisticsMapper.getPlayTrendData(params);
        
        Map<String, Object> result = new HashMap<>();
        List<String> dates = new ArrayList<>();
        List<Long> plays = new ArrayList<>();
        List<Long> views = new ArrayList<>();
        List<Long> clicks = new ArrayList<>();
        
        for (Map<String, Object> item : data) {
            dates.add(getString(item, "date"));
            plays.add(getLongValue(item, "plays"));
            views.add(getLongValue(item, "views"));
            clicks.add(getLongValue(item, "clicks"));
        }
        
        result.put("dates", dates);
        result.put("plays", plays);
        result.put("views", views);
        result.put("clicks", clicks);
        
        return result;
    }

    @Override
    public List<Map<String, Object>> getMaterialPlayRank(String startDate, String endDate, Integer limit) {
        Map<String, Object> params = buildParams(startDate, endDate);
        if (limit != null) {
            params.put("limit", limit);
        }
        
        return statisticsMapper.getMaterialPlayRank(params);
    }

    @Override
    public Map<String, Object> getConversionRate(String startDate, String endDate) {
        Map<String, Object> params = buildParams(startDate, endDate);
        Map<String, Object> data = statisticsMapper.getConversionRate(params);
        
        Map<String, Object> result = new HashMap<>();
        result.put("playToViewRate", getDoubleValue(data, "playToViewRate"));
        result.put("viewToClickRate", getDoubleValue(data, "viewToClickRate"));
        result.put("playToClickRate", getDoubleValue(data, "playToClickRate"));
        
        return result;
    }

    @Override
    public Map<String, Object> getHourlyPlayAnalysis(String startDate, String endDate) {
        Map<String, Object> params = buildParams(startDate, endDate);
        List<Map<String, Object>> data = statisticsMapper.getHourlyPlayAnalysis(params);
        
        Map<String, Object> result = new HashMap<>();
        List<String> hours = new ArrayList<>();
        List<Long> plays = new ArrayList<>();
        List<Long> views = new ArrayList<>();
        
        for (Map<String, Object> item : data) {
            hours.add(getString(item, "hour") + ":00");
            plays.add(getLongValue(item, "plays"));
            views.add(getLongValue(item, "views"));
        }
        
        result.put("hours", hours);
        result.put("plays", plays);
        result.put("views", views);
        
        return result;
    }

    @Override
    public int updatePlayStatistics(Long materialId, Integer duration, Boolean isCompleted) {
        Map<String, Object> params = new HashMap<>();
        params.put("materialId", materialId);
        params.put("duration", duration);
        params.put("isCompleted", isCompleted ? 1 : 0);
        
        return statisticsMapper.updatePlayStatistics(params);
    }

    @Override
    public int updateClickStatistics(Long materialId) {
        return statisticsMapper.updateClickStatistics(materialId);
    }

    private Map<String, Object> buildParams(String startDate, String endDate) {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.hasText(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.hasText(endDate)) {
            params.put("endDate", endDate);
        }
        return params;
    }

    private Long getLongValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return 0L;
        if (value instanceof Number) {
            return ((Number) value).longValue();
        }
        try {
            return Long.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return 0L;
        }
    }

    private Double getDoubleValue(Map<String, Object> map, String key) {
        Object value = map.get(key);
        if (value == null) return 0.0;
        if (value instanceof Number) {
            return ((Number) value).doubleValue();
        }
        try {
            return Double.valueOf(value.toString());
        } catch (NumberFormatException e) {
            return 0.0;
        }
    }

    private String getString(Map<String, Object> map, String key) {
        Object value = map.get(key);
        return value == null ? "" : value.toString();
    }
}